<template>
  <div class="app-container">
    <el-form
      :model="queryParams"
      ref="queryForm"
      :inline="true"
      v-show="showSearch"
      label-width="100px"
    >
      <el-form-item label="集成系统名称" prop="appName">
        <el-input
          v-model="queryParams.appName"
          placeholder="请输入集成系统名称"
          clearable
          size="default"
          style="width: 200px"
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="集成系统标识" prop="appKeyLike">
        <el-input
          v-model="queryParams.appKeyLike"
          placeholder="请输入集成系统标识"
          clearable
          size="default"
          style="width: 200px"
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="集成系统状态" prop="isEnable">
        <el-select
          v-model="queryParams.isEnable"
          placeholder="集成系统状态"
          clearable
          size="default"
          style="width: 200px"
        >
          <el-option
            v-for="dict in stateOptions"
            :key="dict.dictValue"
            :label="dict.dictLabel"
            :value="dict.dictValue"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <search-button @click="handleQuery" :perm="['uni:app:info:search']" />
        <reset-button @click="resetQuery" :perm="['uni:app:info:search']" />
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <add-button @click="handleAdd" :perm="['uni:app:info:insert']" :roleType="['conf']" />
      <import-button @click="handleImport" :perm="['uni:app:info:import']" :roleType="['conf']" text="迁入"></import-button>
      <right-toolbar
        v-model:showSearch="showSearch"
        @query-table="getList"
        :perm="['uni:app:info:search']"
      />
    </el-row>

    <el-table v-loading="loading" :data="appList">
      <el-table-column label="序号" align="center" type="index" width="50" />
      <el-table-column label="集成系统标识" align="center" prop="appKey" width="300" />
      <el-table-column label="集成系统编码" align="center" prop="appCode" width="200" />
      <el-table-column label="集成系统名称" align="center" prop="appName" width="200" />
      <el-table-column label="描述" align="center" prop="appDesc" :show-overflow-tooltip="true" />
      <el-table-column
        label="平台认证方式"
        align="center"
        prop="authType"
        :show-overflow-tooltip="true"
        width="150"
      >
        <template #default="scope">
          <div v-if="scope.row.authType == '0'">公开</div>
          <div v-if="scope.row.authType == '1'">数字签名加密</div>
          <div v-if="scope.row.authType == '10'">ID验签</div>
        </template>
      </el-table-column>
      <el-table-column
        label="集成系统认证方式"
        align="center"
        prop="targetAuthType"
        :show-overflow-tooltip="true"
        width="150"
      >
        <template #default="scope">
          <div v-if="scope.row.targetAuthType == '0'">公开</div>
          <div v-if="scope.row.targetAuthType == '1'">数字签名加密</div>
          <div v-if="scope.row.targetAuthType == '2'">对称加密</div>
          <div v-if="scope.row.targetAuthType == '3'">Token</div>
          <div v-if="scope.row.targetAuthType == '4'">Bearer</div>
          <div v-if="scope.row.targetAuthType == '5'">Basic</div>
          <div v-if="scope.row.targetAuthType == '20'">AnvilToken</div>
        </template>
      </el-table-column>
      <el-table-column label="状态" align="center" width="160">
        <template #default="scope">
          <el-tag :type="scope.row.isEnable === 'Y' ? 'success' : 'danger'" disable-transitions
          >{{ scope.row.isEnable === 'Y' ? '启用' : '禁用' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="更新者" align="center" prop="updateBy" width="100" />
      <el-table-column label="更新时间" align="center" prop="updateTime" width="200" />
      <el-table-column
        label="操作"
        align="center"
        class-name="small-padding fixed-width"
        v-if="hasRoleType(['conf'])"
        width="500"
        fixed="right"
      >
        <template #default="scope">
          <text-download-button
            @click="handleExport(scope.row)"
            :perm="['uni:app:info:export']"
            :roleType="['conf']"
            text="迁出"
          />
          <text-edit-button
            @click="handleUpdate(scope.row)"
            :perm="['uni:app:info:update']"
            :roleType="['conf']"
          />
          <text-reset-button
            v-if="scope.row.authType != '0'"
            @click="handleResetKey(scope.row)"
            :perm="['uni:app:info:update']"
            :roleType="['conf']"
            text="重置Secret"
            title="重置后原有的集成系统将无法接入，是否确认重置?"
          />
          <text-detail-button
            v-if="scope.row.authType != '0'"
            @click="handleView(scope.row)"
            :perm="['uni:app:info:search']"
            :roleType="['conf']"
            text="查看密钥对"
          />
          <text-detail-button
            @click="handleDetails(scope.row)"
            :perm="['uni:app:info:search']"
            :roleType="['conf']"
            text="详细"
          />
          <TextDisableButton
            v-if="scope.row.isEnable === 'Y'"
            @click="handleStatusChange(scope.row)"
            :perm="['uni:app:info:update']"
            :roleType="['conf']"
            text="禁用"
            :title="'是否确认' + '禁用' + '[' + scope.row.appName + ']？'"
          />
          <TextEnableButton
            v-else
            @click="handleStatusChange(scope.row)"
            :perm="['uni:app:info:update']"
            :roleType="['conf']"
            :title="'是否确认' + '启用' + '[' + scope.row.appName + ']？'"
          />
          <text-delete-button
            @click="handleDelete(scope.row)"
            :perm="['uni:app:info:delete']"
            :roleType="['conf']"
            :title="'是否确认删除' + scope.row.appName + '?'"
          />
        </template>
      </el-table-column>
    </el-table>
    <pagination
      v-show="total > 0"
      :total="total"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改参数配置对话框 -->
    <drag-dialog
      :title="title"
      :close-on-click-modal="false"
      v-model="open"
      width="1200px"
      append-to-body
      @close="cancel"
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="150px" :disabled="readOnly">
        <el-form-item label="集成系统名称" prop="appName">
          <el-input v-model="form.appName" placeholder="请输入集成系统名称" />
        </el-form-item>
        <el-form-item label="集成系统编码" prop="appCode">
          <el-input v-model="form.appCode" placeholder="请输入集成系统编码" />
        </el-form-item>
        <el-form-item label="集成系统描述" prop="appDesc">
          <el-input type="textarea" v-model="form.appDesc" placeholder="请输入集成系统描述" />
        </el-form-item>
        <div class="formBox">
          <el-form-item label="平台认证方式" prop="authType">
            <el-radio-group v-model="form.authType">
              <el-radio label="0">公开</el-radio>
              <el-radio label="1">数字签名加密</el-radio>
              <el-radio label="10">ID验签</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="服务URL" prop="appCtxUrl" style="width: 50%">
            <el-input v-model="form.appCtxUrl" placeholder="请输入服务URL" />
          </el-form-item>
        </div>
        <el-form-item label="集成系统认证方式" prop="appText">
          <el-checkbox-group v-model="form.appText" size="mini">
            <el-checkbox-button @change="checkbox(0, '公开')" label="公开" />
            <el-checkbox-button @change="checkbox(1, '数字签名加密')" label="数字签名加密" />
            <el-checkbox-button @change="checkbox(2, '对称加密')" label="对称加密" />
            <el-checkbox-button @change="checkbox(3, 'Token')" label="Token" />
            <el-checkbox-button @change="checkbox(4, 'Bearer')" label="Bearer" />
            <el-checkbox-button @change="checkbox(5, 'Basic')" label="Basic" />
            <el-checkbox-button @change="checkbox(20, 'AnvilToken')" label="AnvilToken" />
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="AppID" prop="targetAuthAppId" v-if="form.targetAuthType == '1'">
          <el-input type="textarea" v-model="form.targetAuthAppId" />
        </el-form-item>
        <el-form-item label="授权类型" v-if="form.targetAuthType == '4'">
          client_credentials
        </el-form-item>
        <el-form-item label="授权地址" prop="targetAuthUrl" v-if="form.targetAuthType == '4'">
          <el-input type="textarea" v-model="form.targetAuthUrl" />
        </el-form-item>
        <el-form-item label="ClientID" prop="targetAuthAppId" v-if="form.targetAuthType == '4'">
          <el-input type="textarea" v-model="form.targetAuthAppId" />
        </el-form-item>
        <!-- <el-form-item label="AppSecret" prop="appSecret" v-if="form.targetAuthType == '1'">
          <el-input type="textarea" v-model="form.appSecret" />
        </el-form-item> -->
        <el-form-item
          label="AppSecret"
          prop="targetAuthAppSecret"
          placeholder="AppSecret"
          v-if="form.targetAuthType == '1'"
        >
          <el-input type="textarea" v-model="form.targetAuthAppSecret" />
        </el-form-item>
        <el-form-item
          label="服务端公钥"
          prop="targetAuthPublicKey"
          v-if="form.targetAuthType == '1'"
        >
          <el-input type="textarea" v-model="form.targetAuthPublicKey" />
        </el-form-item>
        <el-form-item
          label="密钥"
          prop="targetAuthAppSecret"
          placeholder="密钥"
          v-if="form.targetAuthType == '2'"
        >
          <el-input type="textarea" v-model="form.targetAuthAppSecret" />
        </el-form-item>
        <el-form-item
          label="请求头认证"
          prop="targetAuthAppSecret"
          placeholder="请求头认证"
          v-if="form.targetAuthType == '3'"
        >
          <el-input type="textarea" v-model="form.targetAuthAppSecret" />
        </el-form-item>
        <el-form-item
          label="ClientSecret"
          prop="targetAuthAppSecret"
          placeholder="ClientSecret"
          v-if="form.targetAuthType == '4'"
        >
          <el-input type="textarea" v-model="form.targetAuthAppSecret" />
        </el-form-item>
        <el-form-item
          label="用户名"
          prop="targetAuthAppId"
          placeholder="请输入用户名"
          v-if="form.targetAuthType == '5'"
        >
          <el-input type="textarea" v-model="form.targetAuthAppId" />
        </el-form-item>
        <el-form-item
          label="密码"
          prop="targetAuthAppSecret"
          placeholder="请输入密码"
          v-if="form.targetAuthType == '5'"
        >
          <el-input type="textarea" v-model="form.targetAuthAppSecret" />
        </el-form-item>
        <el-form-item
          label="Token名称"
          prop="targetAuthAppSecret"
          placeholder="Token名称"
          v-if="form.targetAuthType == '20'"
        >
          <el-input type="textarea" v-model="form.targetAuthAppSecret" />
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" :disabled="readOnly" @click="submitForm">保 存</el-button>
          <el-button @click="cancel">取 消</el-button>
        </span>
      </template>
    </drag-dialog>

    <!-- 查看密钥对 -->
    <drag-dialog title="查看密钥对" v-model="openDetail" width="800px" append-to-body>
      <el-collapse :value="['1', '2']">
        <el-collapse-item title="公钥" name="1">
          <span v-html="pubKey"></span>
        </el-collapse-item>
        <el-collapse-item title="私钥" name="2">
          <template #title> 私钥<i class="header-icon el-icon-warning"></i></template>
          <el-alert
            type="warning"
            description="由于私钥的隐私性要求，请联系管理员通过其他渠道获取。"
            :closable="false"
          />
        </el-collapse-item>
      </el-collapse>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="openDetail = false">关 闭</el-button>
        </span>
      </template>
    </drag-dialog>

    <drag-dialog
      title="应用私钥，请妥善保管，丢失后请重置！"
      v-model="secretDetail"
      width="800px"
      append-to-body
    >
      <p>{{ secretKey }}</p>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="secretCancel">取消复制</el-button>
          <el-button @click="handleCopy" type="primary">确认复制</el-button>
        </span>
      </template>
    </drag-dialog>

    <!-- 集成系统迁入对话框 -->
    <drag-dialog
      :title="upload.title"
      :close-on-click-modal="false"
      v-model="upload.open"
      width="400px"
      append-to-body
    >
      <el-upload
        ref="upload"
        :limit="1"
        accept=".zip"
        :headers="upload.headers"
        :action="upload.url"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或
          <em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            Tips：迁入迁出主要用于多环境间数据传递，因此不建议用户对迁出的包进行修改
            <div class="el-upload__tip" style="color: red">
              提示：仅允许上传“zip”格式文件！
            </div>
          </div>
        </template>
      </el-upload>
      <template #footer>
        <dialog-footer @ok="submitFileForm" @cancel="cancelUpload" />
      </template>
    </drag-dialog>
  </div>
</template>

<script>
import {
  listApp,
  getApp,
  delApp,
  addApp,
  updateApp,
  resetKey,
  changeAppStatus
} from '@uni/api/uni/app/info'
import { debounceWrapper } from '@/utils/zmids'
import { getToken } from '@/utils/auth'
import defaultSettings from '@/settings'
import TextDisableButton from '@/components/Zmids/Buttons/TextDisableButton.vue'
import TextEnableButton from '@/components/Zmids/Buttons/TextEnableButton.vue'

export default {
  name: 'UniAppInfo',
  components: { TextEnableButton, TextDisableButton },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 参数表格数据
      appList: [],
      // 弹出层标题
      title: '',
      // 是否显示秘钥弹窗
      secretDetail: false,
      // 秘钥
      secretKey: '',
      // 是否显示弹出层
      open: false,
      openDetail: false,
      readOnly: false,
      // 状态数据字典
      stateOptions: [],
      // 集成系统迁入参数
      upload: {
        // 是否显示弹出层
        open: false,
        // 弹出层标题
        title: '',
        // 是否禁用上传
        isUploading: false,
        // 设置上传的请求头部
        headers: { [defaultSettings.tokenName]: 'Bearer ' + getToken() },
        // 上传的地址
        url: import.meta.env.VITE_APP_BASE_API + '/uni/app/info/importZip'
      },
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        orderBy: 'UPDATE_TIME',
        sortDirect: 'DESC',
        appName: undefined,
        isEnable: undefined
      },
      url:
        import.meta.env.VITE_APP_BASE_API +
        (defaultSettings.isCould ? '/system-service' : '') +
        '/custom/upload',
      predefineColors: [
        '#FF4500',
        '#FF8C00',
        '#FFD700',
        '#90EE90',
        '#00CED1',
        '#409EFF',
        '#C71585'
      ],
      pubKey: undefined,
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        appName: [{ required: true, message: '集成系统名称不能为空', trigger: 'blur' }],
        appCode: [{ required: true, message: '集成系统编码不能为空', trigger: 'blur' }]
      }
    }
  },
  created() {
    this.getList()
    this.getDicts('sys_normal_disable').then((response) => {
      this.stateOptions = response.data
    })
  },
  methods: {
    /** 查询参数列表 */
    getList: debounceWrapper(function () {
      this.loading = true
      listApp(this.queryParams).then((response) => {
        this.appList = response.data.list
        this.total = response.data.total
        this.loading = false
      })
    }),
    // 参数系统内置字典翻译
    stateFormat(row, column) {
      return this.selectDictLabel(this.stateOptions, row.isEnable)
    },
    // 取消按钮
    cancel() {
      this.open = false
      this.readOnly = false
      this.reset()
    },
    // 表单重置
    reset() {
      this.form = {
        appName: '',
        appCode: '',
        appText: ['公开'],
        authType: '0',
        targetAuthType: '0',
        appCtxUrl: '',
        appDesc: '',
        appId: '',
        targetAuthUrl: '',
        targetAuthAppId: '',
        appSecret: '',
        portalColor: '#409EFF',
        targetAuthPublicKey: '',
        targetAuthAppSecret: '',
        isEnable: 'Y',
        isAdd: true
      }
      this.resetForm('form')
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm('queryForm')
      this.handleQuery()
    },
    // 迁出
    handleExport: debounceWrapper(function (row) {
      this.downloadUrl('/uni/app/info/exportZip/' + row.appId);
    }),
    // 迁入
    handleImport: debounceWrapper(function () {
      this.upload.title = '集成系统迁入'
      this.upload.open = true
    }),
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true
    },
    // 文件上传成功处理
    handleFileSuccess: debounceWrapper(function (response, file, fileList) {
      this.upload.open = false
      this.upload.isUploading = false
      this.$refs.upload.clearFiles()
      this.$alert(response.msg, '迁入结果', { dangerouslyUseHTMLString: true })
      this.getList()
    }),
    // 提交上传文件
    submitFileForm() {
      this.$refs.upload.submit()
    },
    // 取消上传
    cancelUpload() {
      this.upload.open = false;
      this.upload.isUploading = false;
      this.$refs.upload.clearFiles();
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset()
      this.open = true
      this.title = '新增集成系统'
    },
    /** 修改按钮操作 */
    handleUpdate: debounceWrapper(function (row) {
      this.reset()
      getApp(row.appId).then((response) => {
        this.form = response.data
        let appText = ''
        if (row.targetAuthType == '0') {
          appText = '公开'
        } else if (row.targetAuthType == '1') {
          appText = '数字签名加密'
        } else if (row.targetAuthType == '2') {
          appText = '对称加密'
        } else if (row.targetAuthType == '3') {
          appText = 'Token'
        } else if (row.targetAuthType == '4') {
          appText = 'Bearer'
        } else if (row.targetAuthType == '5') {
          appText = 'Basic'
        } else if (row.targetAuthType == '20') {
          appText = 'AnvilToken'
        }
        this.form.appText = [appText]
        this.form.isAdd = false
        this.open = true
        this.readOnly = false
        this.title = '修改集成系统'
      })
    }),
    /** 提交按钮 */
    submitForm: function () {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          if (!this.form.isAdd) {
            updateApp(this.form).then((response) => {
              if (response.data === 1) {
                this.msgSuccess('修改成功')
                this.open = false
                this.getList()
              }
            })
          } else {
            addApp(this.form).then((response) => {
              if (response.code === '200') {
                this.msgSuccess('新增成功')
                this.open = false
                this.secretDetail = true
                this.secretKey = response.data
              }
            })
          }
        }
      })
    },

    /** 复制秘钥按钮操作 */
    async handleCopy() {
      try {
        await navigator.clipboard.writeText(this.secretKey)
        this.msgSuccess('秘钥复制成功')
        this.secretDetail = false
        this.getList()
      } catch (e) {
        this.msgError('秘钥复制失败，请手动复制')
        console.error('无法复制文本：', e)
      }
    },
    /** 秘钥弹窗关闭 */
    secretCancel: debounceWrapper(function () {
      this.secretDetail = false
      this.getList()
    }),
    /** 详情按钮 */
    handleDetails: debounceWrapper(function (row) {
      this.reset()
      getApp(row.appId).then((response) => {
        this.form = response.data
        let appText = ''
        if (row.targetAuthType == '0') {
          appText = '公开'
        } else if (row.targetAuthType == '1') {
          appText = '数字签名加密'
        } else if (row.targetAuthType == '2') {
          appText = '对称加密'
        } else if (row.targetAuthType == '3') {
          appText = 'Token'
        } else if (row.targetAuthType == '4') {
          appText = 'Bearer'
        } else if (row.targetAuthType == '5') {
          appText = 'Basic'
        } else if (row.targetAuthType == '20') {
          appText = 'AnvilToken'
        }
        // let appText = row.targetAuthType == 1 ? '数字签名加密' : row.targetAuthType == 2 ? '对称加密' : '公开';
        this.form.appText = [appText]
        this.form.isAdd = false
      })
      this.openDisable = true
      this.readOnly = true
      this.open = true
    }),
    /** 删除按钮操作 */
    handleDelete(row) {
      delApp(row.appId)
        .then(() => {
          this.msgSuccess('删除成功')
          this.getList()
        })
        .catch(function () {})
    },
    /** 重置按钮操作 */
    handleResetKey(row) {
      resetKey(row.appId)
        .then((response) => {
          this.secretDetail = true
          this.secretKey = response.data
        })
        .catch(function () {})
    },
    /** 查看公钥按钮操作 */
    handleView(row) {
      this.openDetail = true
      this.secretTitle = '查看密钥对'
      this.pubKey = row.appPubKey
    },
    /** 启用与禁用 */
    handleStatusChange(row) {
      let text = row.isEnable === 'Y' ? '禁用' : '启用'
      changeAppStatus(row.appId, row.isEnable == 'Y' ? 'N' : 'Y').then(() => {
        this.msgSuccess(text + '成功')
        this.getList()
      })
    },
    /** 服务认证按钮操作 */
    checkbox(val, e) {
      this.form.appText = [e]
      this.form.targetAuthType = val
      this.$nextTick(() => {
        this.$refs['form'].clearValidate()
      })
    },
    handleAvatarSuccess(res, file) {
      const obj = this.getCustomUploadTrans(res.data)
      this.form.portalLogo = obj.url
    }
  }
}
</script>

<style lang="scss">
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px !important;
  color: #8c939d !important;
  width: 178px !important;
  height: 178px !important;
  line-height: 178px !important;
  text-align: center !important;
}

.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>
